package cn.sdormitory.workflow.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.sdormitory.basedata.dao.BClassDao;
import cn.sdormitory.basedata.dao.BDormitoryDao;
import cn.sdormitory.basedata.dao.BStudentDao;
import cn.sdormitory.basedata.entity.BClass;
import cn.sdormitory.basedata.entity.BDormitory;
import cn.sdormitory.basedata.entity.BStudent;
import cn.sdormitory.basedata.vo.BClassStudentVo;
import cn.sdormitory.common.sms.TxSmsTemplate;
import cn.sdormitory.common.utils.SecurityUtils;
import cn.sdormitory.common.utils.SysUserUtils;
import cn.sdormitory.school.entity.SchoolDuty;
import cn.sdormitory.smartdor.dao.SdAttenceTrackRecordDao;
import cn.sdormitory.smartdor.entity.SdAttenceTrackRecord;
import cn.sdormitory.sys.dao.SysDeptDao;
import cn.sdormitory.sys.dao.SysDictDetailDao;
import cn.sdormitory.sys.dao.SysUserDao;
import cn.sdormitory.sys.entity.SysDept;
import cn.sdormitory.sys.entity.SysDictDetail;
import cn.sdormitory.sys.entity.SysUser;
import cn.sdormitory.workflow.dao.NotRetrunedApplyDao;
import cn.sdormitory.workflow.service.NotRetrunedApplyService;
import cn.sdormitory.workflow.service.WorkFlowCommonService;
import cn.sdormitory.workflow.vo.NotRetrunedApplyVO;
import cn.sdormitory.workflow.vo.WorkFlowVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.HistoryService;
import org.activiti.engine.history.HistoricTaskInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.annotation.Reference;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;

@Service
@Slf4j
public class NotRetrunedApplyServiceImpl extends ServiceImpl<NotRetrunedApplyDao, NotRetrunedApplyVO> implements NotRetrunedApplyService {

    @Autowired
    private WorkFlowCommonService workFlowCommonService;

    @Resource
    BStudentDao bStudentDao;

    @Resource
    BClassDao bClassDao;

    @Resource
    SysUserDao sysUserDao;

    @Autowired
    private HistoryService historyService;
    @Resource
    BDormitoryDao bDormitoryDao;
    @Resource
    private SdAttenceTrackRecordDao sdAttenceTrackRecordDao;
    @Resource
    private TxSmsTemplate txSmsTemplate;
    @Resource
    SysDictDetailDao sysDictDetailDao;
    @Resource
    SysDeptDao SysDeptDao;


    @Override
    public IPage<NotRetrunedApplyVO> pageList(NotRetrunedApplyVO vo) {
        IPage<NotRetrunedApplyVO> page = new Page<>(vo.getPageNum(), vo.getPageSize());
        String username = SysUserUtils.getSysUser().getUsername();
        if(StringUtils.isEmpty(username)){
            username = vo.getCreateBy();
        }
        if("1".equals(vo.getType())){
            vo.setCreateBy(username);
        }
        if("2".equals(vo.getType())){
            vo.setCurrentApprover(username);
        }
//        vo.getProcessInstanceId()
        return this.baseMapper.getApplyPage(vo,page);
    }

    @Override
    public int createApply(NotRetrunedApplyVO vo) {
        String username = SysUserUtils.getSysUser().getUsername();
        //查询审批人--提交时默认审批人为学生的班主任
        if(StringUtils.isEmpty(vo.getStudentId())){
            log.info("学生ID为空");
            return -1;
        }
        //检查当天学生是不是已经提交过申请单
        LambdaQueryWrapper<NotRetrunedApplyVO> applyWrapper = new LambdaQueryWrapper<>();
        applyWrapper.eq(NotRetrunedApplyVO::getStudentId,vo.getStudentId());
        applyWrapper.eq(NotRetrunedApplyVO::getNotRetrunedDate,vo.getNotRetrunedDate());
        Integer integer = this.baseMapper.selectCount(applyWrapper);
        if(integer > 0){
            return -2;
        }
        String applyNo = DateUtil.format(new Date(),"yyyyMMddHHmmssSSS");
        //获取到班主任ID
        BStudent bStudent = bStudentDao.selectById(vo.getStudentId());
        BClass bClass = bClassDao.selectById(bStudent.getClassId());
        Long approve = bClass.getClassTeacherId();
        SysUser sysUser = sysUserDao.selectById(approve);
        WorkFlowVO flowVO = new WorkFlowVO();
        flowVO.setApplyTitle("宿舍未归寝处理流程");
        flowVO.setApplyID(vo.getApplyId());
        flowVO.setBusinessKey("NR-"+applyNo);
        //查询下级处理人
        Map<String,Object> map =new HashMap<>();

        if("1".equals(vo.getCreateSubmitType())){
            List<String> list = new ArrayList<>();
            list.add(sysUser.getUsername());
            map.put("assignee",list);

        }else if("2".equals(vo.getCreateSubmitType())) {
            List<String> list = new ArrayList<>();
            list.add(sysUser.getUsername());
            list.add(teachPerson().getLeader());
            map.put("assignee",list);
        }

        flowVO.setVariables(map);
        //创建请假工作流
        String processInstanceId = workFlowCommonService.createProcessInstance(flowVO);
        vo.setProcessInstanceId(processInstanceId);
        //更新流程实例ID

        vo.setStudentName(bStudent.getStudentName());
        vo.setClassName(bClass.getClassName());
        vo.setApplyNo("NR-"+applyNo);
        vo.setStudentImg(bStudent.getStuPhoto());
        if(!StringUtils.isEmpty(username)){
            vo.setCreateBy(username);
        }
        vo.setApplyStatus("1");//默认是审批中
        int insert = this.baseMapper.insert(vo);

        LambdaQueryWrapper<NotRetrunedApplyVO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(NotRetrunedApplyVO::getProcessInstanceId, vo.getProcessInstanceId());
        NotRetrunedApplyVO notRetrunedApplyVO = this.baseMapper.selectOne(wrapper);
        //发送通知班主任短信
        sendSMS(sysUser.getPhone(),vo,"提交到班主任处理");
        //发送短信通知宿管中心负责人
        SysDept sysdept = deptInfo("宿管中心");
        sendSMS(sysdept.getPhone(),vo,"提交到班主任处理");
        saveHistory(vo.getCreateSubmitLabel(),"2",notRetrunedApplyVO,username);
        return insert;
    }

    /**
     * 查询宿管中心审批人
     * @return
     */
    private SysDept teachPerson(){
        LambdaQueryWrapper<SysDept> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDept::getName,"宿管中心");
        SysDept sysDept = this.SysDeptDao.selectOne(wrapper);
        return sysDept;
    }
    /**
     * 查询部门信息
     * @return
     */
    private SysDept deptInfo(String deptName){
        LambdaQueryWrapper<SysDept> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDept::getName,deptName);
        SysDept sysDept = this.SysDeptDao.selectOne(wrapper);
        return sysDept;
    }

    private void sendSMS(String phono,NotRetrunedApplyVO notRetrunedApplyVO,String statusVal) {
        //查询宿舍信息
        BDormitory bDormitory = bDormitoryDao.selectById(notRetrunedApplyVO.getSdId());
        LambdaQueryWrapper<SysDictDetail> dictDetailWrapper = new LambdaQueryWrapper<>();
        dictDetailWrapper.eq(SysDictDetail::getDictType,"sys_building");
        dictDetailWrapper.eq(SysDictDetail::getDictValue,bDormitory.getBuildingNo());
        SysDictDetail sysDictDetail = sysDictDetailDao.selectOne(dictDetailWrapper);
        String [] content ={sysDictDetail.getDictLabel()+"-"+bDormitory.getDormitoryNo(),notRetrunedApplyVO.getStudentName(),statusVal};
        txSmsTemplate.sendMesModel(phono,content,7);
    }

    private void saveHistory(String statusVal, String type,NotRetrunedApplyVO notRetrunedApplyVO,String createBy) {
        BDormitory bDormitory = bDormitoryDao.selectById(notRetrunedApplyVO.getSdId());
        SdAttenceTrackRecord SdAttenceTrackRecord = new SdAttenceTrackRecord();
        SdAttenceTrackRecord.setBdormitoryId(bDormitory.getId());
        SdAttenceTrackRecord.setBuildingNo(bDormitory.getBuildingNo());
        SdAttenceTrackRecord.setStorey(bDormitory.getStorey());
        SdAttenceTrackRecord.setDormitoryNo(bDormitory.getDormitoryNo());
        SdAttenceTrackRecord.setType(type);
        SdAttenceTrackRecord.setResult(statusVal);
        SdAttenceTrackRecord.setStudentId(Long.valueOf(notRetrunedApplyVO.getStudentId()));
        SdAttenceTrackRecord.setContactDate(notRetrunedApplyVO.getNotRetrunedDate());
        SdAttenceTrackRecord.setCreateBy(createBy);
        sdAttenceTrackRecordDao.insert(SdAttenceTrackRecord);
    }

    @Override
    public boolean cancelApply(NotRetrunedApplyVO vo) {
        LambdaQueryWrapper<NotRetrunedApplyVO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(NotRetrunedApplyVO::getProcessInstanceId,vo.getProcessInstanceId());
        NotRetrunedApplyVO applyVO = new NotRetrunedApplyVO();
        applyVO.setApplyStatus("2");//撤销流程
        applyVO.setModifyBy(SysUserUtils.getSysUser().getUsername());
        applyVO.setModifyTime(new Date());
        this.baseMapper.update(applyVO,wrapper);
        return workFlowCommonService.cancelApply(vo.getProcessInstanceId(),"");
    }

    @Override
    public NotRetrunedApplyVO applyDetail(NotRetrunedApplyVO vo) {
        LambdaQueryWrapper<NotRetrunedApplyVO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(NotRetrunedApplyVO::getProcessInstanceId,vo.getProcessInstanceId());
        return this.baseMapper.selectOne(wrapper);
    }

    @Override
    public IPage<WorkFlowVO> findHistoryApproval(WorkFlowVO vo) {
        String username = SysUserUtils.getSysUser().getUsername();
        if(StringUtils.isEmpty(username)){
            username = vo.getCreateBy();
        }
        int startNum=(vo.getPageNum()-1)*vo.getPageSize();
        List<HistoricTaskInstance> hisTaskList = historyService.createHistoricTaskInstanceQuery().finished()
                .taskInvolvedUser(username)
                .processDefinitionKey(vo.getApplyID())
                .orderByTaskCreateTime().desc().listPage(startNum,vo.getPageSize());
        Long count = historyService.createHistoricTaskInstanceQuery().finished().taskInvolvedUser(username)
                .processDefinitionKey(vo.getApplyID()).count();
        List<WorkFlowVO> leaveTasks = new ArrayList<>();
        for (HistoricTaskInstance task : hisTaskList) {
//            List<HistoricTaskInstance> hTask = historyService.createHistoricTaskInstanceQuery()
//                    .processDefinitionKey(task.getProcessDefinitionKey()).taskAssignee(username).list();
            WorkFlowVO flowVO = new WorkFlowVO();
            flowVO.setTaskId(task.getId());
            flowVO.setName(task.getName());
            LambdaQueryWrapper<NotRetrunedApplyVO> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(NotRetrunedApplyVO::getProcessInstanceId,task.getProcessInstanceId());
            NotRetrunedApplyVO notRetrunedApplyVO = this.baseMapper.selectOne(wrapper);
            flowVO.setBusinessData(notRetrunedApplyVO);
            flowVO.setProcessInstanceId(task.getProcessInstanceId());
            flowVO.setProcessDefinitionId(task.getProcessDefinitionId());
            flowVO.setCreateTime(task.getStartTime());
            leaveTasks.add(flowVO);
        }
        IPage ipage = new Page();
        ipage.setTotal(count);
        ipage.setRecords(leaveTasks);
        return ipage;
    }
}
